import React, {Component} from "react";
import PropTypes from 'prop-types';

import enroute from 'enroute';
import invariant from 'invariant';

export default class Router extends Component{
  static propTypes = {
    children: PropTypes.element, // React元素
    location: PropTypes.string.isRequired, // 地址
  }
  constructor(props) {
    super(props);
    this.routes = {}; // Router 组件上存储路由
    this.addRoutes(props.children); // 将所有子组件添加到路由
    this.router = enroute(this.routes);
  }
  addRoutes(routes,parent){
    React.Children.forEach(routes, route => this.addRoute(route, parent));
  }
  cleanPath(path) {
    return path.replace(/\/\//g, '/');
  }
  normalizeRoute(path, parent) {
    // 如果只有/，则为绝对路线
    if (path[0] === '/') {
      return path;
    }
    // 没有父元素路线，不需要在一起
    if (!parent) {
      return path;
    }
    // 将子路线加入父路线的后面
    return `${parent.route}/${path}`;
  }


  addRoute(element,parent){
    const {component , path , children} = element.props; // addRoutes 遍历 所有组件，并进行循环执行该函数

    invariant(component,`${component} 缺少相应的组件`);
    invariant(typeof path === 'string',`${path} path属性不是一个字符串`)


    // 要呈现的 Component
    const render = (params , renderProps) => {
      const finalProps = Object.assign({params}, this.props , renderProps);
      const children = React.createElement(component, finalProps);

      return parent ? parent.render(params, { children }) : children;
    }

    const route = this.normalizeRoute(path, parent);
    if (children) {
      this.addRoutes(children, { route, render }); // 如果它子元素不为空，就继续遍历子元素
    }
    // 在routes属性上设置路线
    this.routes[this.cleanPath(route)] = render;


  }

  render() {
    const {location} = this.props;
    invariant(location , '<Router /> 需要一个 location 属性');
    return this.router(location);
  }

}
